﻿using FTBS.Models.Entities;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Transactions;
using System.Data.Objects;
using FTBS.Models.Entities.Concert;

namespace FTBS.Models.DAO
{
    public class CheckOutDAO
    {
        private FilmTicketBookingSystemEntities _entities = new FilmTicketBookingSystemEntities();

        /// <summary>
        /// Generate CodeBooking
        /// </summary>
        /// <author>VuongVT</author>
        /// <returns>CartId</returns>
        public string GenerateCodeBooking()
        {
            string cartId = string.Empty;
            //2 ký tự đầu tiên: Ngày hiện tại
            string day = string.Empty;
            if (DateTime.Now.Day < 10)
            {
                day = "0" + DateTime.Now.Day.ToString();
            }
            else
            {
                day = DateTime.Now.Day.ToString();
            }
            cartId = cartId + day;

            //2 ký tự tiếp theo: Tháng
            string month = string.Empty;
            if (DateTime.Now.Month < 10)
            {
                month = "0" + DateTime.Now.Month.ToString();
            }
            else
            {
                month = DateTime.Now.Month.ToString();
            }
            cartId = cartId + month;

            //2 ký tự tiếp theo: Giờ
            string hours = string.Empty;
            if (DateTime.Now.Hour < 10)
            {
                hours = "0" + DateTime.Now.Hour.ToString();
            }
            else
            {
                hours = hours + DateTime.Now.Hour.ToString();
            }
            cartId = cartId + hours;

            //2 ký tự tiếp theo: Phút
            string minutes = string.Empty;
            if (DateTime.Now.Minute < 10)
            {
                minutes = "0" + DateTime.Now.Minute.ToString();
            }
            else
            {
                minutes = DateTime.Now.Minute.ToString();
            }
            cartId = cartId + minutes;

            //2 ký tự tiếp theo: Giây
            string second = string.Empty;
            if (DateTime.Now.Second < 10)
            {
                second = "0" + DateTime.Now.Second.ToString();
            }
            else
            {
                second = DateTime.Now.Second.ToString();
            }
            cartId = cartId + second;

            return cartId;
        }

        /// <summary>
        /// Add a cart to TicketCart table
        /// </summary>
        /// <param name="codeBooking"></param>
        /// <param name="userName"></param>
        /// <param name="totalPrice"></param>
        /// <param name="totalTicket"></param>
        /// <param name="note"></param>
        /// <param name="createTime"></param>
        /// <returns></returns>
        public string CreateCart(Promotion promotion, string userName, double totalPrice, double actualMoneyReceive, string cartId, int totalTicket, string note)
        {
            try
            {
                TicketCart ticketCart = new TicketCart();
                //CartId is received from Payment
                ticketCart.CartId = cartId;
                    ticketCart.UserName = userName;
                ticketCart.TotalPrice = totalPrice;
                if (actualMoneyReceive >= totalPrice)
                {
                    ticketCart.IsPaid = true;
                }
                else
                {
                    ticketCart.IsPaid = false;
                }
                ticketCart.TotalTicket = totalTicket;
                ticketCart.Note = note;
                if (promotion != null)
                {
                    ticketCart.Note = ticketCart.Note + "+" + promotion.PromotionName;
                }
                //CreateTime is current time
                ticketCart.CreateTime = DateTime.Now;
                _entities.TicketCarts.Add(ticketCart);
                var resultQuery = _entities.SaveChanges();
                if (resultQuery == 1)
                {
                    return ticketCart.CartId;
                }
                else
                {
                    return string.Empty;
                }
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Insert CartId into Ticket, change Status of Ticket to TRUE: Booked
        /// </summary>
        /// <param name="cartId"></param>
        /// <param name="chairId"></param>
        /// <param name="scheduleId"></param>
        /// <returns>1: Success -- 0: Fail</returns>
        public int UpdateCartIdToTicket(string cartId, int ticketId, double price, int scheduleId)
        {
            try
            {
                var ticketItem = (from ticket in _entities.Tickets
                                  where ticket.TicketId == ticketId
                                        && ticket.ScheduleId == scheduleId
                                        && ticket.IsDeleted == false
                                  select ticket).FirstOrDefault();
                //Add CartId which is auto genarated into CartId property of Ticket table
                ticketItem.CartId = cartId;
                //Change Status = true to know this ticket is booked
                ticketItem.Status = true;
                //Add price received into ticket
                ticketItem.Price = price;

                _entities.Entry(ticketItem).State = EntityState.Modified;
                var resultQuery = _entities.SaveChanges();
                return resultQuery;
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Check chair is booked or not
        /// </summary>
        /// <param name="listTicketId">List ticketId</param>
        /// <returns>1: Is Booked -- 0: Not Booked</returns>
        public int CheckTicketBooking(List<int> listTicketId)
        {
            foreach (var ticket in listTicketId)
            {
                //var resultQuery = _entities.Chairs.Find(chair);
                var resultQuery = (from t in _entities.Tickets
                                   where t.TicketId == ticket
                                   select t).FirstOrDefault();
                if (resultQuery.Status == true)
                {
                    return 1;
                }
            }
            return 0;
        }
        public double TotalPrice(List<int> listTicketId) {
            double totalPrice = 0;
            foreach (var ticket in listTicketId)
            {
                //var resultQuery = _entities.Chairs.Find(chair);
                var Price = _entities.Tickets.Where(s => s.TicketId == ticket).Select(s=>s.PurePrice).FirstOrDefault();
                totalPrice = Convert.ToDouble(Price) + totalPrice;
            }
            return totalPrice;
        
        }
        /// <summary>
        /// Create Payment
        /// </summary>
        /// <param name="cartId"></param>
        /// <param name="chargeMoney"></param>
        /// <returns></returns>
        public int CreatePayment(string fullName, string email, string phoneNumber, string cartId, double chargeMoney, double actualMoneyReceive)
        {
            try
            {
                Payment payment = new Payment();
                payment.ChargeMoney = chargeMoney;
                payment.CartId = cartId;
                payment.ActualMoney = actualMoneyReceive;
                payment.PaidTime = DateTime.Now;
                payment.FullName = fullName;
                payment.BankAccount = "Ngân lượng";
                payment.PhoneNumber = phoneNumber;
                payment.Email = email;
                if (actualMoneyReceive >= chargeMoney)
                {
                    payment.IsComplete = true;
                }
                else
                {
                    payment.IsComplete = false;
                }
                _entities.Payments.Add(payment);
                var resultQuery = _entities.SaveChanges();
                return resultQuery;
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Booking a Ticket method
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="totalPrice"></param>
        /// <param name="totalTicket"></param>
        /// <param name="note"></param>
        /// <param name="chairId"></param>
        /// <param name="scheduleId"></param>
        /// <returns>
        ///          0: Don't create a booking
        ///          1: Success
        /// </returns>
        /// <author>VuongVT</author>
        public int BookingTicket(SearchSchedule searchSchedule, Dictionary<int, double> listTicketIdAndPrice, double actualMoneyReceive, string orderCode)
        {
            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    try
                    {
                        //Demo value for payment Ngan Luong
                        actualMoneyReceive = searchSchedule.TotalPrice;

                        //First time create TicketCart. If success, continue insert CartId into Ticket and change status of Ticket
                        string resultCreateTicketCart = CreateCart(searchSchedule.Promotion, searchSchedule.User.UserName, searchSchedule.TotalPrice, actualMoneyReceive, orderCode, listTicketIdAndPrice.Count(), searchSchedule.Note);

                        if (!string.Empty.Equals(resultCreateTicketCart))
                        {
                            //Second time, update CartId and Status of Ticket
                            //1: Success, 0: Fail
                            foreach (var ticket in listTicketIdAndPrice)
                            {
                                int resultUpdateTicket = UpdateCartIdToTicket(resultCreateTicketCart, ticket.Key, ticket.Value, searchSchedule.ScheduleId);
                            }
                            //Create a Payment
                            var resultCreatePayment = CreatePayment(searchSchedule.FullName, searchSchedule.Email, searchSchedule.PhoneNumber, resultCreateTicketCart, searchSchedule.TotalPrice, actualMoneyReceive);
                            if (searchSchedule.User.UserName != null)
                            {
                                var resultUser = (from user in _entities.Users
                                                 where user.UserName == searchSchedule.User.UserName
                                                       && user.IsDeleted == false
                                                 select user).FirstOrDefault();
                                var selectLevel = (from level in _entities.Levels
                                                   where level.LevelId == resultUser.LevelId
                                                         && level.IsDeleted == false
                                                   select level).FirstOrDefault();

                                var selectTheater = (from theater in _entities.Theaters
                                                   where theater.TheaterId == searchSchedule.TheaterId
                                                         && theater.IsDeleted == false
                                                   select theater).FirstOrDefault();

                                if (resultUser != null)
                                {
                                    int currentPoint = 0;
                                    if (resultUser.Point == null)
                                    {
                                        currentPoint = 0;
                                    }
                                    else
                                    {
                                        currentPoint = (int)resultUser.Point;
                                    }
                                    int pointWithMoney = selectTheater.PointWithMoney;
                                    int pointToIncreaseLevel = selectLevel.PointIncreaseLevel;
                                    int pointGot = Convert.ToInt32(actualMoneyReceive) / pointWithMoney;
                                    currentPoint = currentPoint + pointGot;
                                    if (resultUser.LevelId != null)
                                    {
                                        if (resultUser.LevelId == 1)
                                        {
                                            if (currentPoint >= pointToIncreaseLevel)
                                            {
                                                resultUser.LevelId = 3;
                                            }                                            
                                        }
                                    }
                                    else
                                    {
                                        resultUser.LevelId = 1;
                                    }
                                    resultUser.Point = currentPoint;
                                    _entities.Entry(resultUser).State = EntityState.Modified;
                                    var resultQuery = _entities.SaveChanges();
                                }
                            }
                            
                            ts.Complete();
                            if (resultCreatePayment == 0)
                            {
                                return 0;
                            }
                            else
                            {
                                return 1;
                            }
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        ts.Dispose();
                        return 0;
                    }
                }
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Insert CartId for People who payment online successful but the choosen tickets are booked by another people
        /// The system also create the CartId but has the Note = ""Hoàn lại tiền" to notify that the staff have to pay back the money for customer.
        /// </summary>
        /// <param name="searchSchedule"></param>
        /// <param name="listTicketIdAndPrice"></param>
        /// <param name="actualMoneyReceive"></param>
        /// <param name="orderCode"></param>
        /// <returns></returns>
        public int BookingTicketForFailPayment(SearchSchedule searchSchedule, Dictionary<int, double> listTicketIdAndPrice, double actualMoneyReceive, string orderCode)
        {
            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    try
                    {
                        searchSchedule.Note = "Hoàn lại tiền";
                        //First time create TicketCart. If success, continue insert CartId into Ticket and change status of Ticket
                        string resultCreateTicketCart = CreateCart(searchSchedule.Promotion, searchSchedule.User.UserName, searchSchedule.TotalPrice, actualMoneyReceive, orderCode, listTicketIdAndPrice.Count(), searchSchedule.Note);

                        if (!string.Empty.Equals(resultCreateTicketCart))
                        {
                            ////Second time, update CartId and Status of Ticket
                            ////1: Success, 0: Fail
                            //foreach (var ticket in listTicketIdAndPrice)
                            //{
                            //    int resultUpdateTicket = UpdateCartIdToTicket(resultCreateTicketCart, ticket.Key, ticket.Value, searchSchedule.ScheduleId);
                            //}
                            //Create a Payment
                            var resultCreatePayment = CreatePayment(searchSchedule.FullName, searchSchedule.Email, searchSchedule.PhoneNumber, resultCreateTicketCart, searchSchedule.TotalPrice, actualMoneyReceive);
                            ts.Complete();
                            if (resultCreatePayment == 0)
                            {
                                return 0;
                            }
                            else
                            {
                                return 1;
                            }
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        ts.Dispose();
                        return 0;
                    }
                }
            }
            catch (Exception)
            {
                return 0;
            }
        }

        public bool HasUnsavedChanges()
        {
            return _entities.ChangeTracker.Entries().Any(e => e.State == EntityState.Added
                                                      || e.State == EntityState.Modified
                                                      || e.State == EntityState.Deleted);
        }
    }
}